Multiple core computer architectures have become more common in recent times. Such architectures allow code to be run in parallel. For example, in a dual core architecture, a first core can execute a first set of code in a first thread at the same time that a second core is executing a second set of code in a second thread. The first thread could be running a block of code from a first program and a second thread could be running a block of code from a second program. In addition, it is possible for the two threads to be running two blocks of code from the same program. To allow such parallelism, programs can include parallel code, which includes self-scheduling code that specifies code that can be run in parallel during partial or completely overlapping time periods. A compiler can model control and data dependencies for regions of code in an existing program. The compiler can also codify those dependencies and inject new code back into the program so that when a region of the program completes execution, the program can update a set of dependencies that are relevant to successor regions, if any, in the program. If all the dependencies of a successor code region are fulfilled, then the self-scheduling code can initiate that successor to run as a task. This code that initiates successor regions in the program is referred to herein using the terms “self-scheduling code,” “code that is configured to self-schedule,” or similar terms. Many existing programs are written as sequential programs that do not include parallel code.